Namespace("org.wattdepot.gdata.makahiki");

// http://code.google.com/apis/visualization/documentation/gallery/genericimagechart.html

// Requires HtmlTable.js

// Creates a table showing power data from the last few minutes. 
org.wattdepot.gdata.makahiki.PowerLastFewMinutes = function() {
 

  // Generates a datatable for this specific source from the multi-source datatable.
  // The datatable is used to generate a table of the last 10 power values for the given source.
  // Column 0 contains the time in HH:MM:SS format.
  // Column 1 contains the power value associated with that timestamp.
  // Column 2 contains the change in power from the timestamp before this one. 
  function makeDataTable(rollingSecondsDatatable, source) {
    // Create the data table of power values to return.
    var powerTable = new google.visualization.DataTable();
    var numPowerTableRows = 10;
    powerTable.addColumn('date'); // the time of day.
    powerTable.addColumn('number'); // the power in Wh.
    powerTable.addColumn('number'); // the change in power, or blank if it's the last entry.
    powerTable.addRows(numPowerTableRows);
    // Determine the row in the rollingDays table that contains this source's data.
    var rollingPowerSourceRow = findRow(rollingSecondsDatatable, source);
    // Initialize columns 0 and 1 for each of the 10 rows.
    for (var i = 0; i < numPowerTableRows; i++) {
      // Get the power value and timestamp.
      var offset = (i * 2) + 2;
      var timestampVal = rollingSecondsDatatable.getValue(rollingPowerSourceRow, offset);
      var powerVal = rollingSecondsDatatable.getValue(rollingPowerSourceRow, offset + 1);
      powerTable.setCell(i, 0, timestampVal);
      powerTable.setCell(i, 1, powerVal);
    }
    // Now initialize the change column for the first 9 rows.
    for (var i = 1; i < numPowerTableRows; i++) {
      var change = powerTable.getValue((i-1), 1) - powerTable.getValue(i, 1);
      powerTable.setCell((i - 1), 2, change);
    }
    // Now define formatters for the columns
    var dateFormatter = new google.visualization.DateFormat({pattern: 'h:mm:ss a'});
    dateFormatter.format(powerTable, 0);
    return powerTable;
  }
  
  // Returns the row in which source's data is located, or -1 if not found.
  function findRow(datatable, source) {
    for (var i = 0; i < datatable.getNumberOfRows(); i++) {
      if (datatable.getValue(i, 0) == source) {
        return i;
      }
    }
    return -1;
  }

  // Draws the three components (title, table, caption) of the energy visualization.
  function draw(id, source, spreadsheetDatatable, options) {
    // Define look and feel parameters using options object to override defaults. 
    var width = options.width || 300;
    var backgroundColor = options.backgroundColor || "F5F3E5";
    var globalStyle = options.globalStyle || {};
    var titleStyle = options.titleStyle || {};
    var captionStyle = options.captionStyle || {};
    var title = options.title || 'Latest Power Data for ' + source;
    var height = 200;
    var greenColor = '459E00';
    var redColor = 'FF0000';
    // Create a datatable with this source's data. 
    var datatable = makeDataTable(spreadsheetDatatable, source);
    // Get the top-level div where this visualization should go.
    element = document.getElementById(id);
    // Now add the elements.
    addGlobalStyle(element, backgroundColor, width, globalStyle);
    addTitleDiv(element, id, title, titleStyle);
    addTableDiv(element, id, source, datatable, width);
    addSparklineDiv(element, id, datatable, backgroundColor, width);
    addCaptionDiv(element, id, captionStyle);
  }

  // Adds 'global' CSS styling to the top-level div passed into this instance.
  function addGlobalStyle(element, backgroundColor, width, globalStyle) {
    element.style.backgroundColor = backgroundColor;
    element.style.margin = '0 auto';
    element.style.width = width + 'px';
    addStyleProperties(element, globalStyle);
  }

  function addTitleDiv(element, id, title, titleStyle, width) {
    var divId = id + '__Title';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    div.style.textAlign = 'center';
    addStyleProperties(div, titleStyle);
    div.style.width = width + 'px';
    div.innerHTML = title;
  }

  // Updates the divElement style attribute with all properties in styleObject.
  function addStyleProperties(divElement, styleObject) {
    for (key in styleObject) {
      if (styleObject.hasOwnProperty(key)) {
        divElement.style[key] = styleObject[key]; 
      }
    }
  }

  function addTableDiv(element, id, source, datatable, width) {
    var divId = id + '__Chart';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    var table = new org.wattdepot.gdata.HtmlTable();
    table.addAttribute('width=' + width + 'px');
    table.addAttribute('style="text-align: center"');
    table.addRow(['Time', 'Power (watts)', 'Change']);
    table.addTable(datatable, true);
    div.innerHTML = table.getHtml();
  }
  
  function addSparklineDiv(element, id, datatable, backgroundColor, width) {
    var divId = id + '__Sparkline';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    div.style.backgroundColor = backgroundColor;
    var formatter = new google.visualization.ColorFormat();
    formatter.addRange(null, null, 'white', 'orange');
    formatter.format(datatable, 1);
    var view = new google.visualization.DataView(datatable);
    view.setColumns([1]);
    var chart = new google.visualization.LineChart(div);
    chart.draw(view, {vAxis : {minValue : 0},
                      hAxis : {direction : -1},
                      curveType : 'function', 
                      pointSize : 0, 
                      legend: 'none', 
                      backgroundColor: backgroundColor, 
                      width: width, 
                      height: 40});
  }

  function addCaptionDiv(element, id, captionStyle) {
    var divId = id + '__Caption';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    addStyleProperties(div, captionStyle);
    div.innerHTML = 'Shows recent power values. "Change" column shows the change in power since the prior timestamp. Chart displays recent values on right.';
  }

  // Returns the pre-existing element with id 'id', or else creates and returns
  // a new element with type elementType and that id.
  function getElementByIdOrCreate(id, elementType) {
    var element = document.getElementById(id);
    if (element) {
      return element;
    }
    else {
      element = document.createElement(elementType);
      element.setAttribute("id", id);
      return element;
    }
  }

  return {
    // Public interface to this function.
    draw : draw
  };
};
